﻿using System;
using System.Data.Common;
using System.Data;
using Vbyte.SharpOrm.SqlDb;
using System.Collections.Generic;

namespace Vbyte.SharpOrm.Adapter
{
    /// <summary>
    /// 针对Access的适配
    /// </summary>
    public class AccessAdapter : ISqlDbAdapter
    {
        /// <summary>
        /// Sql数据类型映射词典
        /// </summary>
        private static Dictionary<string, string> SqlDbTypeMapDict = new Dictionary<string, string>();

        /// <summary>
        /// Initializes a new instance of the <see cref="AccessAdapter"/> class.
        /// </summary>
        public AccessAdapter()
        {
            InitializeDict(); 
        }

        private void InitializeDict()
        {
            if (SqlDbTypeMapDict.Count == 0)
            {
                SqlDbTypeMapDict.Add(typeof(Single).FullName, "float");
                SqlDbTypeMapDict.Add(typeof(double).FullName, "real");
                SqlDbTypeMapDict.Add(typeof(decimal).FullName, "decimal");
                SqlDbTypeMapDict.Add(typeof(long).FullName, "INTEGER");
                SqlDbTypeMapDict.Add(typeof(int).FullName, "INTEGER");
                SqlDbTypeMapDict.Add(typeof(short).FullName, "smallint");
                SqlDbTypeMapDict.Add(typeof(byte).FullName, "smallint");
                SqlDbTypeMapDict.Add(typeof(Guid).FullName, "uniqueidentifier");
                SqlDbTypeMapDict.Add(typeof(bool).FullName, "BOOLEAN");
                SqlDbTypeMapDict.Add(typeof(DateTime).FullName, "datetime");
                SqlDbTypeMapDict.Add(typeof(byte[]).FullName, "image");
            }
        }

        #region ISqlDbAdapter 成员

        /// <summary>
        /// 获取针对NET CLR基本数据类型的Sql数据类型转换
        /// </summary>
        /// <param name="clrType">NET CLR基本基本类型</param>
        /// <param name="maxLength">可为空的最大长度限制</param>
        /// <returns></returns>
        public string GetNativeType(Type clrType, int? maxLength)
        {
            string strSqlType = "text(255)";
            if (clrType == typeof(string))
            {
                if (maxLength.HasValue)
                {
                    if (maxLength.Value == int.MaxValue)
                    {
                        strSqlType = "text";
                    }
                    else
                    {
                        strSqlType = "text(" + maxLength.Value.ToString() + ")";
                    }
                }
            }
            else if (clrType.IsGenericType
                && clrType.GetGenericTypeDefinition() == typeof(Nullable<>).GetGenericTypeDefinition())
            {
                string keyType = Nullable.GetUnderlyingType(clrType).FullName;
                if (SqlDbTypeMapDict.ContainsKey(keyType))
                {
                    strSqlType = SqlDbTypeMapDict[keyType];
                }
            }
            else
            {
                if (SqlDbTypeMapDict.ContainsKey(clrType.FullName))
                {
                    strSqlType = SqlDbTypeMapDict[clrType.FullName];
                }
            }
            return strSqlType;
        }

        /// <summary>
        /// 获取指定表内最新产生标志的SQL语句获取文本
        /// </summary>
        /// <param name="currentTabName">当前表名，如果为null或空则返回全局标志。</param>
        /// <returns>标志的SQL语句获取文本</returns>
        public string GetIdentitySql(string currentTabName)
        {
            return "select @@identity as id";
        }

        /// <summary>
        /// 标志该数据适配器是否有自己的数据分页实现
        /// </summary>
        /// <returns>实现则为true，否则为false。</returns>
        public bool HasImplementCustomPage()
        {
            return false;
        }

        /// <summary>
        /// 获取满足实例条件的分页数据
        /// </summary>
        /// <param name="dbInstance">数据库辅助实例</param>
        /// <param name="builderInstance">在实例样本上产生的SQL构建适配器</param>
        /// <param name="tabDef">获取实例表定义（备用:获取主键、max函数运算信息）</param>
        /// <param name="currentPage">当前数据页页次</param>
        /// <param name="pageSize">每页显示记录条数</param>
        /// <param name="sharedOpenConnection">当前存在的已打开连接的数据库连接</param>
        /// <param name="command">已生成的数据库操作命令实例</param>
        /// <returns>满足条件的内容数据表</returns>
        public DataTable GetPagedDataTable(ISqlDb dbInstance, ISqlBuilderAdapter builderInstance, SqlTable tabDef, int currentPage, int pageSize,
            DbConnection sharedOpenConnection, DbCommand command)
        {
            Access Svr = (Access)dbInstance;
            string cmdSql = string.Empty;

            if (currentPage == 1)
            {
                cmdSql = string.Format("Select Top {0} {1} from {2} {3} {4} {5}",
                    pageSize,
                    string.Join(",", builderInstance.FieldNamesList), //字段列表
                    builderInstance.VirtualTable,                     //数据来源表
                    builderInstance.SqlCondition,                     //条件限制
                    builderInstance.SqlGroupBy,                       //分组
                    builderInstance.SqlOrderBy);                      //排序
            }
            else
            {
                //颠倒Top + Order By的分页算法
                /*

                 select * from Products where productid in 
                       ( select top 15 productid from 
                         ( select top 1499985 productname,productid from Products 
                             order by productname,productid ) as t 
                          order by t.productname desc,t.productid desc )

                    order by productname,productid 

                 */


                //Max分页 按照主键字段排序
                /*
                  select top 15 * from Products 
                    where productid>= 
                      (SELECT max(productid ) from 
                         (select top 2399986 productid from Products order by productid ) as t )

                     order by productid 
                 
                 */

            }
            command.CommandText = cmdSql;
            return Svr.GetDataTable(sharedOpenConnection, command);
        }

        #endregion
    }
}
